
local Element = import("./Element.lua");

local Text = commonlib.inherit(Element);

Text:Property("Value", "");                -- 文本值

-- 处理实体字符

function Text:ctor()
	self:SetName("Text");

	self.texts = {};
end

function Text:Init(xmlnode, window, parent)
    Text._super.Init(self, xmlnode, window, parent);

    self:SetValue(xmlnode.text or "");
	self:SetTagName("text");

	local inline_style = self:GetStyle():GetInlineStyle();
	inline_style.display = "inline";

    return self;
end

function Text:Clone()
	local clone = Text:new():Init(self:GetXmlNode(), self:GetWindow(), self:GetParentElement());
	clone:SetValue(self:GetValue());
	return clone;
end

function Text:GetWhiteSpace()
    return self:GetParent():GetStyleValue("white-space", "normal");
end

function Text:GetTextAlign()
    return self:GetParent():GetStyleValue("text-align", "left");
end

function Text:GetTextOverflow()
    return self:GetParent():GetStyleValue("text-overflow", "auto");
end

function Text:FormatText(text)
	text = string.gsub(text, "&?nbsp;", " ");
	text = string.gsub(text, "\t", "    ");
	text = string.gsub(text, "^%s*", "");
	text = string.gsub(text, "%s*$", "");
	text = string.gsub(text, "\r\n", "\n");
	
	local whiteSpace = self:GetWhiteSpace();

	if (whiteSpace == "pre" or whiteSpace == "pre-line") then
	else  -- normal
		text = string.gsub(text, "\n", " ");
	end

	return text;
end

function Text:SetText(value)
	if (value == self:GetValue()) then return end
	self:SetValue(value or "");
	self:UpdateLayout();
end

function Text:GetText()
	return self:FormatText(self:GetValue());
end

function Text:GetTextLineWidthHeight(text, width, left, top)
	local line_text, remaining_text = self:GetTextByWidth(text, width);
	if(line_text == "") then return 0, 0 end
	
	local textWidth = self:GetTextWidth(line_text);
	local textHeight = self:GetLineHeight();
	local textObject = {text = line_text, x = left, y = top};
	table.insert(self.texts, textObject);
	
	local textAlign = self:GetTextAlign();
	if(width and width > 0 and width > textWidth and textAlign) then
		if(textAlign == "right") then
			textObject.x = left + width - textWidth;
		elseif(textAlign == "center") then
			textObject.x = left + (width - textWidth) / 2;
		end
	end

	-- print_if(self:GetParent():GetAttrId(), string.format("parent_id = %s, x = %s, y = %s, width = %s, height = %s, text = %s, remain_text = %s", textObject.x, textObject.y, self:GetParent():GetAttrId(), textWidth, textHeight, line_text, remaining_text));
	
	if (remaining_text and remaining_text ~= "") then
		local remainingWidth, remainingHeight = self:GetTextLineWidthHeight(remaining_text, width, left, top + textHeight);
		textWidth = math.max(textWidth, remainingWidth);
		textHeight = textHeight + remainingHeight;
	end

	return textWidth, textHeight;
end

function Text:OnUpdateLayout()
	local maxTextWidth = self:GetParent():GetLayout():GetContentWidthHeight();
	local left, top = 0, 0;
	local textWidth, textHeight = 0, 0;
	local text = self:GetText();
	self.texts = {};

	if (self:GetWhiteSpace() == "nowrap") then
		--  不换行
		textWidth = self:GetTextWidth(text);
		textHeight = self:GetLineHeight();

		local textObject = {text = text, x = 0, y = 0};
		table.insert(self.texts, textObject);

		if (maxTextWidth < textWidth) then
			local text_overflow = self:GetTextOverflow();
			if (text_overflow == "ellipsis") then
				textObject.text = self:GetTextByWidth(text, maxTextWidth - 21);
				textObject.text = textObject.text .. "...";
			elseif (text_overflow == "clip") then
				textObject.text = self:GetTextByWidth(text, maxTextWidth);
			else 
			end
		end
	else
		-- 自动换行
		local textlines = commonlib.split(text, "\n");
		for _, textline in ipairs(textlines) do
			local linewidth, lineheight = self:GetTextLineWidthHeight(textline, maxTextWidth, left, top + textHeight);
			textWidth = math.max(linewidth, textWidth);
			textHeight = textHeight + lineheight;
		end
	end

	self:GetLayout():SetWidthHeight(textWidth, textHeight);

	-- print_if(self:GetParent():GetAttrId(), string.format("parent_id = %s, width = %s, height = %s", self:GetParent():GetAttrId(), width, height));

    return true; 
end

-- 绘制文本
function Text:OnRender()
    local x, y, w, h = self:GetPosition();
	local lineheight = self:GetLineHeight();
	self:ApplyStyleFontToPaint();
	for i = 1, #self.texts do
		local obj = self.texts[i];
		self:DrawText(x + obj.x, y + obj.y, w, lineheight, obj.text);
	end
end

return Text;